﻿#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
//#include <unistd.h> // 用于usleep函数
#include <Windows.h>

#define FLOORS 8
#define MAX_PASSENGERS 1000
#define SIMULATION_TIME 1000
#define PROB_GENERATE 0.03

// 电梯状态
typedef enum {
    IDLE,
    UP,
    DOWN,
    LOADING
} ElevatorState;

// 乘客结构
typedef struct {
    int id;
    int start_floor;
    int target_floor;
    int call_time;
    int pickup_time;
} Passenger;

// 电梯结构
typedef struct {
    int current_floor;
    ElevatorState state;
    int target_floor;
    int passengers[MAX_PASSENGERS];
    int count;
    int direction_changes;
} Elevator;

// 楼层结构
typedef struct {
    int up_calls;
    int down_calls;
    int passengers_waiting;
} Floor;

// 模拟系统
typedef struct {
    Floor floors[FLOORS];
    Elevator elevators[2];
    Passenger passengers[MAX_PASSENGERS];
    int total_passengers;
    int time;
    int mode; // 1:单电梯 2:双电梯独立 3:双电梯协同
} Simulation;

// 初始化模拟系统
void init_simulation(Simulation* sim, int mode) {
    sim->time = 0;
    sim->total_passengers = 0;
    sim->mode = mode;

    for (int i = 0; i < FLOORS; i++) {
        sim->floors[i].up_calls = 0;
        sim->floors[i].down_calls = 0;
        sim->floors[i].passengers_waiting = 0;
    }

    for (int i = 0; i < 2; i++) {
        sim->elevators[i].current_floor = 0;
        sim->elevators[i].state = IDLE;
        sim->elevators[i].target_floor = -1;
        sim->elevators[i].count = 0;
        sim->elevators[i].direction_changes = 0;
    }
}

// 生成乘客
void generate_passenger(Simulation* sim) {
    if (sim->total_passengers >= MAX_PASSENGERS) return;

    Passenger* p = &sim->passengers[sim->total_passengers];
    p->id = sim->total_passengers;
    p->call_time = sim->time;

    // 上行乘客 (80%从1楼出发)
    if (rand() % 2 == 0) {
        if (rand() % 100 < 80) {
            p->start_floor = 0; // 1楼
        }
        else {
            p->start_floor = rand() % (FLOORS - 1); // 2-7楼
        }
        do {
            p->target_floor = rand() % FLOORS;
        } while (p->target_floor <= p->start_floor);
    }
    // 下行乘客 (80%到1楼)
    else {
        p->start_floor = 1 + rand() % (FLOORS - 1); // 2-8楼
        if (rand() % 100 < 80) {
            p->target_floor = 0; // 1楼
        }
        else {
            do {
                p->target_floor = rand() % (FLOORS - 1);
            } while (p->target_floor >= p->start_floor);
        }
    }

    // 记录呼叫
    if (p->target_floor > p->start_floor) {
        sim->floors[p->start_floor].up_calls++;
    }
    else {
        sim->floors[p->start_floor].down_calls++;
    }

    sim->floors[p->start_floor].passengers_waiting++;
    sim->total_passengers++;
}

// 决策函数 - 协同模式
int should_pickup(Simulation* sim, int elev_id, int floor) {
    if (sim->mode != 3) return 1; // 非协同模式总是接客

    Elevator* e = &sim->elevators[elev_id];
    Elevator* other = &sim->elevators[1 - elev_id];

    // 如果另一部电梯更近且方向正确
    int dist_current = abs(e->current_floor - floor);
    int dist_other = abs(other->current_floor - floor);

    if (dist_other < dist_current &&
        ((other->state == UP && floor > other->current_floor) ||
            (other->state == DOWN && floor < other->current_floor))) {
        return 0;
    }

    return 1;
}

// 更新电梯状态
void update_elevator(Simulation* sim, int elev_id) {
    Elevator* e = &sim->elevators[elev_id];
    Floor* f = &sim->floors[e->current_floor];

    // 处理到达目标楼层
    if (e->current_floor == e->target_floor) {
        e->state = LOADING;
        e->target_floor = -1;
    }

    // 处理上下客
    if (e->state == LOADING) {
        // 下客
        for (int i = 0; i < e->count; i++) {
            if (e->passengers[i] == e->current_floor) {
                for (int j = i; j < e->count - 1; j++) {
                    e->passengers[j] = e->passengers[j + 1];
                }
                e->count--;
                i--;
            }
        }

        // 上客 (只接方向一致的乘客)
        if ((f->up_calls > 0 && (e->state == UP || e->state == IDLE)) ||
            (f->down_calls > 0 && (e->state == DOWN || e->state == IDLE))) {

            int passengers_to_pickup = f->passengers_waiting;
            if (passengers_to_pickup > 0) {
                for (int i = 0; i < sim->total_passengers; i++) {
                    Passenger* p = &sim->passengers[i];
                    if (p->start_floor == e->current_floor && p->pickup_time == 0) {
                        if (should_pickup(sim, elev_id, e->current_floor)) {
                            if (e->count < MAX_PASSENGERS) {
                                e->passengers[e->count++] = p->target_floor;
                                p->pickup_time = sim->time;
                                f->passengers_waiting--;

                                // 清除呼叫
                                if (p->target_floor > p->start_floor) {
                                    f->up_calls--;
                                }
                                else {
                                    f->down_calls--;
                                }
                            }
                        }
                    }
                }
            }
        }

        e->state = IDLE;
    }

    // 寻找新目标
    if (e->state == IDLE) {
        // 检查当前楼层是否有呼叫
        if ((f->up_calls > 0 || f->down_calls > 0) && should_pickup(sim, elev_id, e->current_floor)) {
            e->state = LOADING;
            return;
        }

        // 寻找最近呼叫
        int closest_distance = FLOORS + 1;
        int closest_floor = -1;

        for (int i = 0; i < FLOORS; i++) {
            if (sim->floors[i].up_calls > 0 || sim->floors[i].down_calls > 0) {
                int distance = abs(i - e->current_floor);
                if (distance < closest_distance) {
                    closest_distance = distance;
                    closest_floor = i;
                }
            }
        }

        if (closest_floor != -1) {
            e->target_floor = closest_floor;
            e->state = (closest_floor > e->current_floor) ? UP : DOWN;
        }
    }

    // 移动电梯
    if (e->state == UP && e->current_floor < FLOORS - 1) {
        e->current_floor++;
    }
    else if (e->state == DOWN && e->current_floor > 0) {
        e->current_floor--;
    }
}

// 可视化函数
void visualize(Simulation* sim) {
    printf("\nTime: %d\n", sim->time);
    printf("Passengers: %d\n", sim->total_passengers);

    // 显示楼层状态
    for (int i = FLOORS - 1; i >= 0; i--) {
        printf("F%d [", i + 1);
        printf("%d↑ %d↓ %dW]  ",
            sim->floors[i].up_calls,
            sim->floors[i].down_calls,
            sim->floors[i].passengers_waiting);

        // 显示电梯位置
        for (int j = 0; j < 2; j++) {
            if (sim->elevators[j].current_floor == i) {
                switch (sim->elevators[j].state) {
                case IDLE: printf("E%d:■ ", j + 1); break;
                case UP: printf("E%d:↑ ", j + 1); break;
                case DOWN: printf("E%d:↓ ", j + 1); break;
                case LOADING: printf("E%d:↕ ", j + 1); break;
                }
                printf("(%dP) ", sim->elevators[j].count);
            }
            else {
                printf("          ");
            }
        }
        printf("\n");
    }

    // 显示等待时间
    int avg_wait = 0;
    for (int i = 0; i < sim->total_passengers; i++) {
        if (sim->passengers[i].pickup_time > 0) {
            avg_wait += sim->passengers[i].pickup_time - sim->passengers[i].call_time;
        }
    }
    if (sim->total_passengers > 0) {
        avg_wait /= sim->total_passengers;
    }
    printf("Avg Wait: %d sec\n", avg_wait);
}

// 运行模拟
void run_simulation(int mode) {
    Simulation sim;
    srand(time(NULL));

    init_simulation(&sim, mode);

    for (sim.time = 0; sim.time < SIMULATION_TIME; sim.time++) {
        // 生成新乘客
        if ((double)rand() / RAND_MAX < PROB_GENERATE) {
            generate_passenger(&sim);
        }

        // 更新电梯
        if (mode == 1) {
            // 单电梯模式 (只使用电梯0)
            update_elevator(&sim, 0);
        }
        else {
            // 双电梯模式
            update_elevator(&sim, 0);
            update_elevator(&sim, 1);
        }

        // 可视化
        if (sim.time % 20 == 0) {
            visualize(&sim);
            Sleep(1500); // Windows 休眠200ms
            //usleep(200000); // 暂停200ms
        }
    }

    // 最终统计
    int total_wait = 0;
    int max_wait = 0;
    for (int i = 0; i < sim.total_passengers; i++) {
        int wait = sim.passengers[i].pickup_time - sim.passengers[i].call_time;
        total_wait += wait;
        if (wait > max_wait) max_wait = wait;
    }

    printf("\n=== Simulation Results (Mode: %d) ===\n", mode);
    printf("Total Passengers: %d\n", sim.total_passengers);
    printf("Average Wait Time: %.2f sec\n", (float)total_wait / sim.total_passengers);
    printf("Max Wait Time: %d sec\n", max_wait);
    printf("Elevator 0 Direction Changes: %d\n", sim.elevators[0].direction_changes);
    if (mode != 1) {
        printf("Elevator 1 Direction Changes: %d\n", sim.elevators[1].direction_changes);
    }
}

int main() {
    printf("Running Single Elevator Mode...\n");
    run_simulation(1);

    printf("\nRunning Independent Elevators Mode...\n");
    run_simulation(2);

    printf("\nRunning Cooperative Elevators Mode...\n");
    run_simulation(3);

    return 0;
}